package com.threadPool;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: dong peng
 * @date: 2019/7/25 14:09
 * @description: 多线程顺序打印
 */

public class ThreadOrderPrint {


    public static void main(String[] args) {
        MySerivce mySerivce = new MySerivce();
        MyThread t1 = new MyThread(mySerivce,"A");
        MyThread t2 = new MyThread(mySerivce,"B");
        MyThread t3 = new MyThread(mySerivce,"C");

        t1.start();
        t2.start();
        t3.start();
    }


    static class MyThread extends Thread {

        private MySerivce mySerivce;
        private String s;

        public MyThread(MySerivce mySerivce,String s) {
            this.mySerivce = mySerivce;
            this.s = s;
        }

        @Override
        public void  run() {
            for(int i = 0; i < 10; i++) {
                switch (s) {
                    case "A": mySerivce.executeA(); break;
                    case "B": mySerivce.executeB(); break;
                    case "C": mySerivce.executeC(); break;
                }

            }

        }

    }


    static class MySerivce {
        Lock lock = new ReentrantLock();
        private static int nextT = 0;

        Condition conditionA = lock.newCondition();
        Condition conditionB = lock.newCondition();
        Condition conditionC = lock.newCondition();

        public void  executeA() {
            try {
                lock.lock();

                try {
                    while (nextT % 3 != 0) {
                        conditionA.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "A");
                nextT = 1;
                conditionB.signal();

            } finally {
                lock.unlock();
            }

        }

        public void  executeB() {
            try {
                lock.lock();

                try {
                    while (nextT % 3 != 1) {
                        conditionB.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "B");
                nextT = 2;
                conditionC.signal();
            } finally {
                lock.unlock();
            }
        }

        public void  executeC() {
            try {
                lock.lock();

                try {
                    while (nextT % 3 != 2) {
                        conditionC.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "C");
                nextT = 0;
                conditionA.signal();
            }finally {
                lock.unlock();
            }

        }
    }
}
